﻿//PlazaErrors.cs
//Copyright (c) 2013 StockSharp LLC, all rights reserved.
//This code module is part of StockSharp library.
//This code is licensed under the GNU GENERAL PUBLIC LICENSE Version 3.
//See the file License.txt for the license details.
//More info on: http://stocksharp.com

namespace StockSharp.Plaza
{
	using System;
	using System.Collections.Generic;
	using System.Runtime.InteropServices;

	using Ecng.Common;

	/// <summary>
	/// Описание кодов ошибок, полученных от Plaza
	/// </summary>
	static class PlazaErrors
	{
		private static readonly Dictionary<int, List<string>> _plazaErrorGroup;

		private static readonly List<string> _common;
		private static readonly List<string> _messages;
		private static readonly List<string> _connection;
		private static readonly List<string> _router;
		private static readonly List<string> _ini;
		private static readonly List<string> _log;
		private static readonly List<string> _messageQueue;
		private static readonly List<string> _messageQueueCrypt;
		private static readonly List<string> _database;
		private static readonly List<string> _service;
		private static readonly List<string> _replication;
		private static readonly List<string> _crypt;
		private static readonly List<string> _asNs;
		private static readonly List<string> _vm;
		private static readonly List<string> _messageQueueAsNs;
		private static readonly List<string> _acl;
		private static readonly List<string> _messageQueueStat;
		private static readonly List<string> _p2Svc;
		private static readonly List<string> _parser;
		private static readonly List<string> _test;
		private static readonly List<string> _isamsm;

		static PlazaErrors()
		{
			_common = new List<string>
			{
				// Возвращается в случае успешного выполнения.
				"P2ERR_OK",
				// Ошибка выделения памяти.
				"P2ERR_COMMON_NO_MEMORY",
				// Некорректные значения аргументов. При возможности следует передавать более конкретную информацию. Например, для передачи NULL можно вернуть и этот код, а обнаружение битого сообщения лучше обозначать отдельным кодом.
				"P2ERR_COMMON_WRONG_ARGUMENTS",
				// Неожиданная ошибка (подробности см. в логе).
				"P2ERR_COMMON_INTERNAL_ERROR",
				// Неожиданная ошибка в системном вызове.
				"P2ERR_COMMON_SYSCALL_FAILED",
				// Выдается в случае, когда какая-либо фича в данной версии не реализована.
				"P2ERR_COMMON_NOT_IMPLEMENTED",
				// Объект до конца не проинициализирован. Инициализация зависит от внешних факторов, на которые вызывающий повлиять не может.
				"P2ERR_COMMON_OBJECT_NOT_INITED",
				// Буфер, переданный для заполнения, меньше чем нужно.
				"P2ERR_COMMON_BUFFER_TOO_SMALL",
				// Буфер, переданный для заполнения, больше чем нужно.
				"P2ERR_COMMON_BUFFER_TOO_LARGE",
				// Ошибка возвращается в цепочечном обработчике и показывает, дальнейшая обработка не нужна.
				"P2ERR_COMMON_MESSAGE_WAS_INTERCEPTED",
				// Конфликт версий разных модулей.
				"P2ERR_COMMON_INVALID_INTERFACE_VERSION",
				// В строке нет ожидаемого завершающего нуля.
				"P2ERR_COMMON_BAD_STRING",
				// Используется как стандартное неаварийное завершение енумератора с колбэком.
				"P2ERR_COMMON_CANCEL_ENUM",
				// Код завершения процесса в случае фатальной ошибки. Для совместимости с Plaza-I значение должно равняться 13.
				"P2ERR_COMMON_EXITCODE_FATAL",
				"P2ERR_COMMON_OVERFLOW",
				"P2ERR_COMMON_REAL_SIZE_RETURNED",
				"P2ERR_COMMON_NOT_SUPPORTED",
				"P2ERR_COMMON_ALREADY_INITIALIZED",
				// Смешение отладочных и релизных модулей в одной программе.
				"P2ERR_COMMON_WRONG_BUILD",
				// Универсальный код для ошибки повторного определения чего-либо.
				"P2ERR_COMMON_ALREADY_DEFINED",
				// Код завершения процесса, убитого снаружи.
				"P2ERR_COMMON_EXITCODE_TERMINATED",
				// Аналог FALSE.
				"P2ERR_NOT_OK",
				// Размер внутреннего буфера записи не равен размеру, переданному в параметрах.
				"P2ERR_BUFFER_SIZES_MISMATCH",
				"P2ERR_COMMON_WRONG_INI_PARAMETER",
				"P2ERR_COMMON_NOT_INITIALIZED",
				"P2ERR_COMMON_TIMEOUT",
				"P2ERR_COMMON_OPEN_FILE_MAPPING_FAILED",
				"P2ERR_COMMON_INVALID_OBJECT_STATE",
				"P2ERR_COMMON_LAST"
			};

			_messages = new List<string>
			{
				// Запрошенного поля в сообщении не существует или его не возможно извлечь.
				"P2ERR_MSG_FIELD_NOT_FOUND",
				// Фиксированный заголовок сообщения испорчен.
				"P2ERR_MSG_BAD_MESSAGE_SIGNATURE",
				// Переменный заголовок сообщения испорчен.
				"P2ERR_MSG_WRONG_OFFSETS_IN_MESSAGE",
				// Обозначает все ошибки данного диапазона, которые не описаны.
				"P2ERR_MSG_SHIT_HAPPENS",
				// Блок не может быть разобран в функциях *Parse*.
				"P2ERR_MSG_BAD_PARSE_BLOCK",
				"P2ERR_MSG_LAST"
			};

			_connection = new List<string>
			{
				// Common socket errors
				// (use WSAGetLastError() to get extended information)
				// Couldn't create socket
				"P2ERR_CONN_SOCK_CREATE",
				// Couldn't bind socket
				"P2ERR_CONN_SOCK_BIND",
				// Couldn't prepare socket address
				"P2ERR_CONN_SOCK_MAKEADDR",
				// Couldn't connect socket
				"P2ERR_CONN_SOCK_CONNECT",
				// Error in WSAEventSelect()
				"P2ERR_CONN_SOCK_EVTSELECT",
				// Couldn't listen socket
				"P2ERR_CONN_SOCK_LISTEN",
				// Error in socket operation
				"P2ERR_CONN_SOCK_ERROR",
				// Couldn't initialize WinSock
				"P2ERR_CONN_WINSOCK_INIT",
				// Socket closed
				"P2ERR_CONN_SOCK_CLOSED",
				// Timeout in socket operation
				"P2ERR_CONN_SOCK_TIMEOUT",
				// Common thread errors
				// (use GetLastError() to get extended information)
				// Couldn't start thread
				"P2ERR_CONN_THREAD_START",
				// Common IOCP errors
				// (use GetLastError() to get extended information)
				// Couldn't create IOCP
				"P2ERR_CONN_IOCP_CREATE",
				// Couldn't associate device with IOCP
				"P2ERR_CONN_IOCP_ASSOCDEV",
				// Couldn't post status through IOCP
				"P2ERR_CONN_IOCP_STATPOST",
				// Couldn't get status from IOCP
				"P2ERR_CONN_IOCP_STATGET",
				// Invalid object state for this operation
				// Object is dead (can be released)
				"P2ERR_CONN_OBJ_IS_DEAD",
				// Invalid state of listener
				"P2ERR_CONN_INVSTATE_LISTENER",
				// Invalid state of connection
				"P2ERR_CONN_INVSTATE_CONNECTION",
				// Invalid state of encryptor
				"P2ERR_CONN_INVSTATE_ENCRYPTOR",
				// Invalid state of msg-connection
				"P2ERR_CONN_INVSTATE_MSGCONNECTION",
				// No free keys in the specified range
				"P2ERR_CONN_NO_FREE_KEYS",
				// Invalid IOCP key
				"P2ERR_CONN_INVALID_KEY",
				// Couldn't start listener thread
				// (use GetLastError() to get extended information)
				"P2ERR_CONN_THSTART_LISTENER",
				// Low level messages (LL)
				// Invalid system type
				"P2ERR_CONN_LL_INVALID_SYS_TYPE",
				"P2ERR_CONN_LL_SIZE_TOOBIG",
				"P2ERR_CONN_LL_BAD_SIGNATURE",
				"P2ERR_CONN_LL_WITHOUT_BODY",
				// Reading INI settings
				// Couldn't read required value
				"P2ERR_CONN_INI_NO_REQ_VALUE",
				"P2ERR_CONN_INI_INVALID_VALUE",
				"P2ERR_CONN_LAST"
			};

			_router = new List<string>
			{
				// Роутер не может выдать маршрут до узла.
				"P2ERR_ROUTE_NO_ROUTE",
				// Неправильно сформирован адрес.
				"P2ERR_ROUTE_INVALID_ADDRESS",
				// Возвращает PostIfForeignAddress, если пакет предназначен не нам. 
				"P2ERR_ROUTE_POSTED_TO_FOREIGN_ADDRESS",
				// Возвращает GetRoute, если адрес принадлежит нам.
				"P2ERR_ROUTE_ME_ITSELF",
				// Возвращает SetNodeName при попытке присвоить имя, не сбросив предыдущее.
				"P2ERR_ROUTE_NODE_NAME_YET_ASSIGNED",
				"P2ERR_ROUTE_NO_FLAG_TO_ROUTE",
				"P2ERR_ROUTE_LAST"
			};

			_ini = new List<string>
			{
				"P2ERR_INI_ALREADY_STARTED",
				"P2ERR_INI_NOT_STARTED",
				"P2ERR_INI_WRITE_ERROR",
				// Полученное значение обрезано до заданных пределов.
				"P2ERR_INI_VALUE_TRUNCATED",
				"P2ERR_INI_FILE_NOT_FOUND",
				// Invalid INI handle specified
				"P2ERR_INI_INVALID_INI_HANDLE",
				"P2ERR_INI_LAST"
			};

			_log = new List<string>
			{
				"P2ERR_LOG_ALREADY_OPENED",
				"P2ERR_LOG_NOT_OPENED_YET",
				"P2ERR_LOG_INVALID_INI_VALUE",
				"P2ERR_LOG_INVALID_LOG_HANDLE",
				"P2ERR_LOG_LAST"
			};

			_messageQueue = new List<string>
			{
				// MQ library already initialized
				"P2ERR_MQ_ALREADY_INITIALIZED",
				// MQ library not initialized yet
				"P2ERR_MQ_NOT_INITIALIZED_YET",
				// Connection already connected
				"P2ERR_MQ_ALREADY_CONNECTED",
				"P2ERR_MQ_NOT_CONNECTED_YET",
				"P2ERR_MQ_TIMEOUT",
				// Received incorrect LL-message
				"P2ERR_MQ_INCORRECT_LLMSG",
				// Protocol MQ-P2router is broken
				"P2ERR_MQ_PROTOCOL_ERROR",
				// Original message in the PostReply not a send-message
				"P2ERR_MQ_ORIGMSG_NOT_SEND",
				// Incorrect value in the field Addr_from of original message
				"P2ERR_MQ_ORIGMSG_BAD_ADDR_FROM",
				// Connection must be reopened (Disconnect() and then Connect())
				"P2ERR_MQ_INVALID_CONNECTION",
				// Invalid connection handle specified (by example, handle used after free)
				"P2ERR_MQ_INVALID_CONN_HANDLE",
				// Socket errors
				// Couldn't create socket
				"P2ERR_MQ_SOCK_CREATE",
				// Couldn't bind socket
				"P2ERR_MQ_SOCK_BIND",
				// Couldn't prepare socket address
				"P2ERR_MQ_SOCK_MAKEADDR",
				// Couldn't connect socket
				"P2ERR_MQ_SOCK_CONNECT",
				// Error in socket operation
				"P2ERR_MQ_SOCK_ERROR",
				// Couldn't initialize WinSock
				"P2ERR_MQ_WINSOCK_INIT",
				// Socket closed
				"P2ERR_MQ_SOCK_CLOSED",
				// Low level messages (LL)
				// Invalid system type
				"P2ERR_MQ_LL_INVALID_SYS_TYPE",
				"P2ERR_MQ_LL_SIZE_TOOBIG",
				"P2ERR_MQ_LL_BAD_SIGNATURE",
				// Other
				// Invalid destination address
				"P2ERR_MQ_INVALID_DESTINATION",
				"P2ERR_MQ_CONNECTION_BUSY",
				"P2ERR_MQ_MULTGET_ABORTED",
				// Original(send) message not found for post reply
				"P2ERR_MQ_ORIG_MSG_NOT_FOUND",
				"P2ERR_MQ_NODE_NAME_CHANGED",
				"P2ERR_MQ_UNEXPECTED_GRNT_CONF",
				"P2ERR_MQ_GRNT_NOT_EXISTS",
				// Попытка несанкционированного доступа.
				"P2ERR_MQ_ACCESS_DENY",
				"P2ERR_MQ_LAST"
			};

			_messageQueueCrypt = new List<string>
			{
				"P2ERR_MQCRYPT_ALREADY_CONNECTED",
				// Connection not ready for this operation
				"P2ERR_MQCRYPT_CONN_NOT_READY",
				// Bad name or wrong password …
				"P2ERR_MQCRYPT_BAD_AUTH_INFO",
				"P2ERR_MQCRYPT_NO_AUTH_INFO",
				// Make logout before login
				"P2ERR_MQCRYPT_ALREADY_LOGED_IN",
				// Current login aborted by logout
				"P2ERR_MQCRYPT_LOGIN_ABORTED",
				// Name of AS not set in the INI
				"P2ERR_MQCRYPT_AS_NAME_NOT_SET",
				// Not set name of DLL for specified AS driver
				"P2ERR_MQCRYPT_ASDLL_NAME_NOT_SET",
				// Couldn't load DLL of AS driver
				"P2ERR_MQCRYPT_LOAD_ASDLL",
				// Data not encrypted or something wrong
				"P2ERR_MQCRYPT_NOT_ENCRYPTED_OR_BAD",
				// String is not hex representation of data
				"P2ERR_MQCRYPT_NOT_HEX_STRING",
				// Router already logged in by another application and can be logged out only by it
				"P2ERR_MQCRYPT_LOGOUT_NOT_BY_OWNER",
				// Login not permitted for this application
				"P2ERR_MQCRYPT_LOGIN_NOT_PERMITTED",
				"P2ERR_MQCRYPT_LAST"
			};

			_database = new List<string>
			{
				// Ошибка открытия соединения.
				"P2ERR_DB_OPEN_ERROR",
				"P2ERR_DB_DRIVER_ERROR",
				// Указано несуществующее имя поля.
				"P2ERR_DB_NO_SUCH_FIELD",
				"P2ERR_DB_NO_SUCH_TABLE",
				"P2ERR_DB_NOT_SUPPORTED_BY_DRIVER",
				"P2ERR_DB_BAD_RECORDSET",
				"P2ERR_DB_EOF",
				"P2ERR_DB_EMPTY_SHEME",
				"P2ERR_DB_WRONG_DB_SCHEME",
				"P2ERR_DB_CANT_BE_DONE_WITHOUT_SCHEME",
				"P2ERR_DB_INVALID_TYPE",
				// Исполнение команды не привело к созданию рекордсета.
				"P2ERR_DB_NO_RECORDSET_RETURNED",
				"P2ERR_DB_CANT_INSERT_EMPTY_RECORD",
				"P2ERR_DB_CANT_CLOSE_WITH_ACTIVE_OBJECTS",
				"P2ERR_DB_RECORD_NOT_FETCHED",
				"P2ERR_DB_CANT_BE_DONE_WITH_SCHEME",
				"P2ERR_DB_NO_RECORD",
				"P2ERR_DB_COMMIT_WITHOUT_TRANSACTION",
				"P2ERR_DB_COMMIT_AFTER_ROLLBACK",
				"P2ERR_DB_ROLLBACK_WITHOUT_TRANSACTION",
				"P2ERR_DB_NESTED_TRANSACTION_AFTER_ROLLBACK",
				"P2ERR_DB_READONLY_RECORD",
				"P2ERR_DB_KEY_FIELD_NOT_SET",
				"P2ERR_DB_FIELD_NOT_SET",
				"P2ERR_DB_DUPLICATE_KEYS",
				"P2ERR_DB_FIELD_IS_NULL",
				"P2ERR_DB_BUSY",
				"P2ERR_DB_NOT_CONNECTED",
				"P2ERR_DB_ALREADY_CONNECTED",
				"P2ERR_DB_NO_SUCH_ITEM",
				"P2ERR_DB_WRONG_ITEM_TYPE",
				"P2ERR_DB_NO_SUCH_VIEW",
				"P2ERR_DB_NO_SUCH_INDEX",
				"P2ERR_DB_DATABASE_IS_CORRUPTED",
				"P2ERR_DB_NON_UNIQUE_INDEX_VALUE",
				"P2ERR_DB_UNIQUE_INDEX_REQUIRED",
				"P2ERR_DB_CANT_TRUNCATE_IN_TRANSACTION",
				"P2ERR_DB_CANT_CHANGE_UNDER_ENUM",
				"P2ERR_DB_CANT_BE_DONE_WITHOUT_INDEX",
				"P2ERR_DB_CANT_SAVE_IN_TRANSACTION",
				"P2ERR_DB_WRONG_P2TIME_DATA_FORMAT",
				"P2ERR_DB_CANT_LOAD_IN_TRANSACTION",
				"P2ERR_DB_BUSY_NO_ROLLBACK",
				"P2ERR_DB_ROLLBACK_REQUIRED",
				"P2ERR_DB_NESTED_TRANSACTION",
				"P2ERR_DB_CANT_SET_OPTIONS_IN_TRANSACTION",
				"P2ERR_DB_TRANSACTION_REQUIRED",
				"P2ERR_DB_LAST"
			};

			_service = new List<string>
			{
				// Specified service already registered for specified address
				"P2ERR_SERV_ALREADY_REGISTERED",
				// Incorrect exclude address specified for resolve
				"P2ERR_SERV_INCORRECT_EXCLUDE_ADDR",
				"P2ERR_SERV_NO_SERVICE",
				"P2ERR_SERV_LAST"
			};

			_replication = new List<string>
			{
				"P2ERR_REPL_WRONG_STATE",
				"P2ERR_REPL_SCHEME_ALREADY_SET",
				// Not error, for internal use only
				"P2ERR_REPL_OBJECT_CHANGED__",
				"P2ERR_REPL_SERVICE_WAS_UNREGISTERED",
				"P2ERR_REPL_PROTOCOL_ERROR",
				// Внутренняя ошибка.
				"P2ERR_REPL_UNUSED_0",
				"P2ERR_REPL_CHANNEL_DISCONNECT_ON_TIMEOUT",
				"P2ERR_REPL_PROTOCOL_VERSION_MISMATCH",
				// Посылается клиентам при закрытии сервера репликации.
				"P2ERR_REPL_SERVER_SHUTDOWN",
				"P2ERR_REPL_ACCESS_DENIED",
				"P2ERR_REPL_LIFE_NUMBER_MISMATCH",
				"P2ERR_REPL_RECONNECT",
				"P2ERR_REPL_WRONG_SCHEME",
				"P2ERR_REPL_NO_SERVICE",
				"P2ERR_REPL_TIMEOUT",
				"P2ERR_REPL_REDIRECT_TO_SNAPSHOT_SERVER",
				"P2ERR_REPL_LAST"
			};

			_crypt = new List<string>
			{
				"P2ERR_CRYPT_NOTAVAIL",
				"P2ERR_CRYPT_NOT_INITED",
				"P2ERR_CRYPT_NOT_EXITING",
				"P2ERR_CRYPT_POINTER",
				"P2ERR_CRYPT_ERROR",
				"P2ERR_CRYPT_RANDOM",
				"P2ERR_CRYPT_UNKNOWN_CTX_TYPE",
				"P2ERR_CRYPT_UNSUPPORTED_CTX_VERSION",
				"P2ERR_CRYPT_INVALID_CTX",
				"P2ERR_CRYPT_OKSPECIAL",
			};

			_asNs = new List<string>
			{
				// Все ошибки P2ERR*, которые происходят на сервере и никак не связаны с корректностью аутентификационной информации, будут переданы удаленному узлу как P2ERR_ASNS_INTERNAL. Дополнительная информация будет содержаться в логах AS.
				"P2ERR_ASNS_INTERNAL",
				"P2ERR_ASNS_PROTOCOL_VERSION_MISMATCH",
				"P2ERR_ASNS_CRYPT_ALGO",
				"P2ERR_ASNS_CRYPT_MODE",
				// Неверный формат аутентификационного запроса.
				"P2ERR_ASNS_BAD_AUTHREQUEST",
				// Неизвестный инициатор (по нему нет информации на сервере).
				"P2ERR_ASNS_INITIATOR_UNKNOWN",
				// Некорректны пароль инициатора.
				"P2ERR_ASNS_INITIATOR_BAD",
				// Неизвестный акцептор (по нему нет информации на сервере).
				"P2ERR_ASNS_ACCEPTOR_UNKNOWN",
				// Некорректны пароль акцептора.
				"P2ERR_ASNS_ACCEPTOR_BAD",
				"P2ERR_ASNS_IP_BLOCKED",
				"P2ERR_ASNS_TOO_LONG_KEY",
				"P2ERR_ASNS_TOO_SHORT_KEY",
				"P2ERR_ASNS_CORRUPTED_KEY",
				"P2ERR_ASNS_LAST",
			};

			_vm = new List<string>
			{
				"P2ERR_VM_WRONG_LEXEME",
				"P2ERR_VM_SYNTAX_ERROR",
				"P2ERR_VM_NUMERIC_OVERFLOW",
				"P2ERR_VM_ILLEGAL_OPCODE",
				"P2ERR_VM_VARIABLE_NOT_SET",
				"P2ERR_VM_STACK_UNDERFLOW",
				"P2ERR_VM_WRONG_VARIABLE_TYPE",
				"P2ERR_VM_WRONG_BLOCK_FORMAT",
				"P2ERR_VM_OPERATION_NOT_ALLOWED",
				"P2ERR_VM_VAR_ZERO",
				"P2ERR_VM_DLL_NOT_FOUND",
				"P2ERR_VM_FUNCTION_NOT_FOUND",
				"P2ERR_VM_DUPLICATED_EXT_FUNC",
				"P2ERR_VM_STACK_BOUNDS_EXCEEDED",
				"P2ERR_VM_FUNCTION_EXEC_ERROR",
				"P2ERR_VM_LAST"
			};

			_messageQueueAsNs = new List<string>
			{
				"P2ERR_MQASNS_PROTOCOL_VERSION_MISMATCH",
				"P2ERR_MQASNS_CRYPT_POLITICS",
				"P2ERR_MQASNS_CRYPT_ALGO",
				"P2ERR_MQASNS_CRYPT_MODE",
				// Random number not valid. Intrusion warning
				"P2ERR_MQASNS_RANDOM_NUMBER",
				// Time mark is not valid. Intrusion warning
				"P2ERR_MQASNS_TIME_MARK",
				// Invalid token format or broken token
				"P2ERR_MQASNS_TOKEN",
				"P2ERR_MQASNS_CRYPTO_PACKET",
				"P2ERR_MQASNS_STATE_CHANGED",
				"P2ERR_MQASNS_STATE_INVALID",
				"P2ERR_MQASNS_CRC",
				"P2ERR_MQASNS_TOKEN_EXPIRED",
				"P2ERR_MQASNS_INVALID_IP",
				"P2ERR_MQASNS_LAST"
			};

			_acl = new List<string>
			{
				"P2ERR_ACL_ROLE_ALREADY_EXISTS",
				"P2ERR_ACL_USER_ALREADY_EXISTS",
				"P2ERR_ACL_UNKNOWN_ROLE",
				"P2ERR_ACL_UNKNOWN_RIGHT",
				"P2ERR_ACL_UNKNOWN_USER",
				"P2ERR_ACL_BAD_BLOCK",
				"P2ERR_ACL_LZO_INIT",
				"P2ERR_ACL_LZO_COMPRESS",
				"P2ERR_ACL_VERSION_MISMATCH",
				"P2ERR_ACL_BAD_SIGNATURE",
				"P2ERR_ACL_LAST"
			};

			_messageQueueStat = new List<string>
			{
				"P2ERR_MQSTAT_ALREADY_REGISTERED",
				"P2ERR_MQSTAT_NOT_REGISTERED",
				"P2ERR_MQSTAT_ALREADY_ANNOUNCED",
				"P2ERR_MQSTAT_NOT_ANNOUNCED",
				"P2ERR_MQSTAT_LAME_STATISTIC",
				"P2ERR_MQSTAT_INVALID_QUERY",
				"P2ERR_MQSTAT_INVALID_NAME",
				"P2ERR_MQSTAT_INVALID_CATEGORY",
				"P2ERR_MQSTAT_LAST"
			};

			_p2Svc = new List<string>
			{
				"P2ERR_P2SVC_LOGIN_FAILED",
				"P2ERR_P2SVC_LOGIN_TIMEOUT",
				"P2ERR_P2SVC_LAST"
			};

			_parser = new List<string>
			{
				"P2ERR_PARSE_NULL_NOT_ALLOWED",
				"P2ERR_PARSE_BUFFER_OVERRUN"
			};

			_test = new List<string>
			{
				"P2ERR_TEST_TIMEOUT",
				"P2ERR_TEST_ERROR",
				"P2ERR_TEST_LAST"
			};

			_isamsm = new List<string>
			{
				"P2ERR_ISAMSM_CANNOT_CREATE_FILE_TO_MAP",
				"P2ERR_ISAMSM_FILE_MAPPING_FAILED",
				"P2ERR_ISAMSM_CANNOT_MAP_VIEW",
				"P2ERR_ISAMSM_NESTED_TRANSACTIONS",
				"P2ERR_ISAMSM_FREE_MEM_TIMEOUT",
				"P2ERR_ISAMSM_CREATE_EVENT_FAILED",
				"P2ERR_ISAMSM_OPEN_EVENT_FAILED",
				"P2ERR_ISAMSM_CANNOT_START_THREAD",
				"P2ERR_ISAMSM_REPL_PROCESS_FAILED",
				//Используется restorer'ом, когда он при чтении доходит до конца mapped-файла.
				"P2ERR_ISAMSM_EOF",
				// Сигнализирует об ошибочном состоянии БД.
				"P2ERR_ISAMSM_ROLLBACK_REQUIRED",
				// Любое изменения БД необходимо осуществлять в транзакции.
				"P2ERR_ISAMSM_TRANSACTION_REQUIRED",
				// Нельзя делать load или truncate после того, как P2ReplSharedMem'у были отданы данные для репликации.
				"P2ERR_ISAMSM_OPERATION_NOT_ALLOWED",
				"P2ERR_ISAMSM_LOAD_TRUNCATE_REQUIRED",
				"P2ERR_ISAMSM_FILE_VERSION_MISMATCH",
				"P2ERR_ISAMSM_LAST"
			};

			_plazaErrorGroup = new Dictionary<int, List<string>>
			{
				{ 0x0000 >> 12, _common },
				{ 0x1000 >> 12, _messages },
				{ 0x2000 >> 12, _connection },
				{ 0x3000 >> 12, _router },
				{ 0x4000 >> 12, _ini },
				{ 0x5000 >> 12, _log },
				{ 0x6000 >> 12, _messageQueue },
				{ 0x7000 >> 12, _messageQueueCrypt },
				{ 0x8000 >> 12, _database },
				{ 0x9000 >> 12, _service },
				{ 0xA000 >> 12, _replication },
				{ 0xB000 >> 12, _crypt },
				{ 0xC000 >> 12, _asNs },
				{ 0xD000 >> 12, _vm },
				{ 0xE000 >> 12, _messageQueueAsNs },
				{ 0xF000 >> 12, _acl },
				{ 0x10000 >> 12, _messageQueueStat },
				// {0x11000,P2ERR_BL},
				{ 0x12000 >> 12, _p2Svc },
				{ 0x13000 >> 12, _parser },
				{ 0x14000 >> 12, _test },
				{ 0x15000 >> 12, _isamsm },
			};
		}

		public static string GetErrorText(this COMException error)
		{
			if (error == null)
				throw new ArgumentNullException("error");

			var errorCode = error.ErrorCode;

			var key = (errorCode & 0xFFFF) >> 12;
			var index = errorCode & 0xFFF;

			if (_plazaErrorGroup.ContainsKey(key))
			{
				var group = _plazaErrorGroup[key];

				return index <= group.Count ? group[index] : "error code not found: 0x{0:x}".Put(errorCode);
			}
			else
				return "error type not found: 0x{0:x}".Put(errorCode);
		}
	}
}